package com.dartfar.base.dao;

import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.type.Type;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;

import com.dartfar.base.model.Person;
import com.dartfar.organize.model.Department;
import com.dartfar.util.GenericsUtils;


@Component("daoUtil")
public class DaoImplUtil<T> implements DaoUtil<T> {

	@Resource
	private HibernateTemplate hibernateTemplate; 

	protected Class<T> persistentClass = GenericsUtils.getSuperClassGenricType(this.getClass());
	

	/**
	 * 删除对象
	 * @param t 对象
	 */
	@Override
	public void delete(T t) {
		hibernateTemplate.delete(t);
	}

	/**
	 * 获取对象
	 * @param id ID
	 * @return 对象
	 */
	@SuppressWarnings("unchecked")
	@Override
	public T get(int id,Class<T> classT) {
		return (T)this.hibernateTemplate.get(classT, id);
	}
	
	/**
	 * 根据HQL获取对象
	 * @param HQL
	 * @return 对象
	 */
	@Override
	public Object get(String hql){
		List list = hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(hql).list();
		if(list != null && list.size() > 0){
			if(list.size() == 1){
				return list.get(0);
			}else{
				System.out.println("数据大于一条");
				return null;
			}
		}else{
			return null;
		}
	}


	/**
	 * 保存
	 * @param t 对象
	 * @return 对象ID
	 */
	@Override
	public int save(T t) {
		return (Integer)this.hibernateTemplate.save(t);
	}

	
	/**
	 * 修改对象
	 * @param t 对象
	 */
	@Override
	public void update(T t) {
		this.hibernateTemplate.update(t);
	}
	
	/**
	 * 更新 hql
	 * @param hql
	 */
	@Override
	public void execute(String hql) {
		System.out.println("hql: " + hql);
		hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(hql).executeUpdate();
		//hibernateTemplate.getSessionFactory().getCurrentSession().createSQLQuery(hql);
	}

	/**
	 * 获取对象列表
	 * @param hql 语句
	 * @param objects 参数值
	 * @param types 参数类型
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<T> getList(String hql, Object[] objects, Type[] types) {
		return (List<T>)hibernateTemplate.getSessionFactory().getCurrentSession()
								.createQuery(hql)
								.setParameters(objects, types)
								.list();
	}
	
	/**
	 * 获取对象列表
	 * @param hql 语句
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<T> getList(String hql) {
		return (List<T>)hibernateTemplate.getSessionFactory().getCurrentSession()
								.createQuery(hql)
								.list();
	}
	
	/**
	 * 根据获取对象列表
	 * @param hql
	 * @param code
	 * @param person
	 * @param depart
	 * @return
	 */
	@Override
	public List<T> getListByAut(String hql, String code, Person person, Department depart){
		String hql_aut = hqlAutConvert(code, person, depart);
		hql = hqlConvert(hql, hql_aut);
		return (List<T>)hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(hql).list();
	}
	
	/**
	 * 获取对象数量
	 * @param hql 语句
	 * @param objects 参数值
	 * @param types 参数类型
	 * @return 数量
	 */
	@Override
	public long getCount(String hql, Object[] objects, Type[] types) {
		return (Long)hibernateTemplate.getSessionFactory().getCurrentSession()
									.createQuery("select count(*) "+hql)
									.setParameters(objects, types)
									.uniqueResult();	
	}
	
	/**
	 * 获取对象数量
	 * @param hql 语句
	 * @return 数量
	 */
	@Override
	public Long getCount(String hql) {
		return (Long)hibernateTemplate.getSessionFactory().getCurrentSession()
										.createQuery("select count(*) "+hql)
										.uniqueResult();	
	}
	
	/**
	 * 根据权限获取数量
	 * @param hql
	 * @param code
	 * @param person
	 * @param depart
	 * @return
	 */
	@Override
	public long getCountByAut(String hql, String code, Person person, Department depart){
		String hql_aut = hqlAutConvert(code, person, depart);
		hql = hqlConvert(hql, hql_aut);
		return (Long)hibernateTemplate.getSessionFactory().getCurrentSession()
		.createQuery("select count(*) "+hql)
		.uniqueResult();	
	}
	
	/**
	 * 获取翻页列表
	 * @param hql 语句
	 * @param objects 参数
	 * @param types 参数类型
	 * @param offset 起始数
	 * @param length 长度
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<T> getListForPage(final String hql,final Object[] objects,final Type[] types,final int pageNo, final int pageSize) {
		List<T> list = (List<T>)hibernateTemplate.executeFind(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				return session.createQuery(hql)
								.setParameters(objects, types)
								.setFirstResult(pageNo)
								.setMaxResults(pageSize)
								.list();
			}	
		});
		return list;
	}
	
	/**
	 * 获取翻页列表
	 * @param hql 语句
	 * @param offset 起始数
	 * @param length 长度
	 * @return 翻页列表
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<T> getListForPage(final String hql, final int pageNo, final int pageSize) {
		List<T> list = (List<T>)hibernateTemplate.executeFind(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				return session.createQuery(hql)
								.setFirstResult(pageNo)
								.setMaxResults(pageSize)
								.list();
			}	
		});
		return list;
	}
	
	/**
	 * 根据权限获取翻页列表
	 * @param hql 语句
	 * @param offset 起始数
	 * @param length 长度
	 * @return 翻页列表
	 */
	@Override
	public List<T> getListForPageByAut(String hql, String code, Person person, Department depart, int pageNo, int pageSize){
		
		final int offset = (pageNo - 1) * pageSize;
		final int length = pageSize;
		
		String hql_aut = hqlAutConvert(code, person, depart);
		final String autHql = hqlConvert(hql, hql_aut);
		List<T> list = (List<T>)hibernateTemplate.executeFind(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				return session.createQuery(autHql)
								.setFirstResult(offset)
								.setMaxResults(length)
								.list();
			}	
		});
		return list;
	}
	
	/**
	 * 批量操作(修改，删除)
	 * @param entities 集合
	 */
	@Override
	public void deleteAll(Collection<T> entities) {
		hibernateTemplate.deleteAll(entities);
	}
	
	
	
	/**
	 * autCode转换
	 * @param code, person
	 */
	public String hqlAutConvert(String code, Person person, Department depart){
		String hql_aut = "";
		if(code == null || code.length() == 0){
			code = "view";
		}
		if ("view".equals(code)){
			hql_aut = "personId = " + person.getPersonId();
		}else if("viewDepart".equals(code)){
			hql_aut = "departId = " + depart.getId();
		}else if ("viewParentDepart".equals(code)){
			hql_aut = "departId = " + depart.getParentId();
		}else if ("viewAll".equals(code)){
			hql_aut = "1 = 1";
		}
		return hql_aut;
	}
	
	/**
	 * hql语句转换
	 * @param hql语句
	 */
	public String hqlConvert(String hql, String hql_aut){
		String hql_begin = "";
		String hql_end = "";
		
		//如果语句中存在WHERE并且存在ORDER
		if(hql.indexOf("where") != -1 && hql.indexOf("order") != -1){
			hql_begin = hql.substring(0, hql.indexOf("order") - 1);
			hql_end = hql.substring(hql.indexOf("order") - 1, hql.length());
			hql = hql_begin + " and " + hql_aut + hql_end;
			System.out.println("AAAA");
		}else 
		
		//如果语句中不存在WHERE并且存在ORDER
		if(hql.indexOf("where") == -1 && hql.indexOf("order") != -1){
			hql_begin = hql.substring(0, hql.indexOf("order") - 1);
			hql_end = hql.substring(hql.indexOf("order") - 1, hql.length());
			hql = hql_begin + " where " + hql_aut + hql_end;
			System.out.println("BBBB");
		}else
			
		//如果语句中不存在WHERE并且不存在ORDER
		if(hql.indexOf("where") == -1 && hql.indexOf("order") == -1){
			hql_begin = hql;
			hql_end = "";
			hql = hql_begin + " where " + hql_aut + hql_end;
			System.out.println("CCCC");
		}else
			
		//如果语句中存在WHERE并且不存在ORDER
		if (hql.indexOf("where") != -1 && hql.indexOf("order") == -1){
			hql_begin = hql;
			hql_end = "";
			hql = hql_begin + " and " + hql_aut + hql_end;
			System.out.println("DDDDDD");
		}
		
		return hql;
	}
	
	
}
